package db

import (
	"encoding/json"
	"fmt"
	"qkcoupon/errorcode"
	"qkcoupon/models"
	"time"

	log "github.com/cihub/seelog"
)

/*
 *@note  创建优惠劵信息
 *@param cc: *PSQkCouponCreateCouponReq
 *@param startTick: 开始时间
 *@param endTick: 结束时间
 *@return (int64,uint): (记录ID,错误码)
 */
func CreateCoupon(cc *models.PSQkCouponCreateCouponReq, startTick int64, endTick int64, totalNum int32) (int64, uint) {
	sql := "INSERT INTO coupon_info(ctype,utype,lmode,bid,rwid,sum,discount,max_discount,time_range,start_tick,end_tick,total_num)VALUES(?,?,?,?,?,?,?,?,?,?,?,?)"

	var rwids = []byte{}
	var timeRange = []byte{}
	var err error

	if cc.Rwids != nil {
		rwids, err = json.Marshal(cc.Rwids)
		//rwids, err = proto.Marshal(cc.Rwids)
		if err != nil {
			log.Warn(err.Error())
		}
	}

	if cc.TimeRanges != nil {
		timeRange, err = json.Marshal(cc.TimeRanges)
		//timeRange, err = proto.Marshal(cc.TimeRanges)
		if err != nil {
			log.Warn(err.Error())
		}
	}

	//log.Debugf("sql:%s", sql)

	lastId, err := qingkeMysqlHelper.Insert(sql,
		cc.Ctype, cc.Utype, cc.Lmode, cc.Bid,
		rwids, cc.Sum, cc.Discount, cc.MaxDiscount,
		timeRange, startTick, endTick, totalNum)

	if err != nil {
		log.Warn(err.Error())
		return 0, errorcode.EC_QKCOUPON_CREATE_COUPON_FAIL
	}

	return lastId, errorcode.EC_GL_SUCCESS
}

func shareCouponRule2CouponBase(scr *models.PSQkCouponShareCouponRule) *models.PSQkCouponCreateCouponReq {
	req := &models.PSQkCouponCreateCouponReq{}
	req.Ctype = scr.Ctype
	req.Utype = int32(models.EQKCOUPON_UTYPE_SHARE_COUPON_USER)
	req.Lmode = scr.Lmode
	req.Sum = scr.Sum
	req.Discount = scr.Discount
	return req
}

/*
 *@note  创建分享优惠劵信息
 *@param uid: 用户ID
 *@param cscp: *PSQkCouponCreateShareCouponParam结构体
 *@param scrl: *models.QSQkCouponShareCouponRuleList结构体
 *@return (uint): (错误码)
 */
func CreateShareCoupon(uid string, cscp *models.PSQkCouponCreateShareCouponParam, scrl *models.PSQkCouponShareCouponRuleList) uint {
	var maxExpiryDay int32
	var timeLayout = "2006.01.02 15:04:05"
	loc, _ := time.LoadLocation("Local")
	curTick := time.Now().Unix()
	var startTick int64
	var endTick int64
	var timeStr string
	var tmpTick time.Time
	var err error

	sql := "INSERT INTO share_cid (share_id, cid) VALUES "

	for _, scr := range scrl.List {
		ccp := shareCouponRule2CouponBase(scr)

		startTick = curTick
		timeStr = time.Unix(curTick, 0).Format("2006.01.02") + " 00:00:00"
		tmpTick, err = time.ParseInLocation(timeLayout, timeStr, loc)
		if err == nil {
			startTick = tmpTick.Unix()
		}

		endTick = curTick + int64(scr.ExpiryDay*models.DAY_UNIT)
		timeStr = time.Unix(endTick, 0).Format("2006.01.02") + " 23:59:59"
		tmpTick, err = time.ParseInLocation(timeLayout, timeStr, loc)
		if err == nil {
			endTick = tmpTick.Unix()
		}

		cid, errCode := CreateCoupon(ccp, startTick, endTick, scr.Count)
		if errCode != errorcode.EC_GL_SUCCESS {
			log.Debugf("create coupon failed!")
			continue
		}

		sql += fmt.Sprintf("('%s', %d),", cscp.ShareId, cid)

		if scr.ExpiryDay > maxExpiryDay {
			maxExpiryDay = scr.ExpiryDay
		}
	}

	sql = sql[:len(sql)-1]

	//log.Debugf("sql:%s", sql)

	_, err = qingkeMysqlHelper.Exec(sql)
	if err != nil {
		log.Warn(err.Error())
		return errorcode.EC_GL_EXEC_SQL_FAIL
	}

	endTick = curTick + int64(maxExpiryDay*models.DAY_UNIT)
	timeStr = time.Unix(endTick, 0).Format("2006.01.02") + " 23:59:59"
	tmpTick, err = time.ParseInLocation(timeLayout, timeStr, loc)
	if err == nil {
		endTick = tmpTick.Unix()
	}

	sql = "INSERT INTO share_info(share_id,sharer,add_num,total_num,expire_tick)VALUES(?,?,?,?,?)"
	//log.Debugf("sql:%s", sql)
	_, err = qingkeMysqlHelper.Insert(sql, cscp.ShareId, uid, 0, scrl.Count, endTick)

	if err != nil {
		log.Warn(err.Error())
		return errorcode.EC_QKCOUPON_CREATE_SHARE_COUPON_FAIL
	}

	return errorcode.EC_GL_SUCCESS
}

func recommendCouponRule2CouponBase(rr *models.PSQkCouponRecommendRule, operator models.EQKCOUPON_OPERATOR) *models.PSQkCouponCreateCouponReq {
	req := &models.PSQkCouponCreateCouponReq{}
	req.Ctype = rr.Ctype

	if operator == models.EQKCOUPON_OPERATOR_RECOMMENDER {
		req.Utype = int32(models.EQKCOUPON_UTYPE_RECOMMENDED_RETURN_USER)
	} else {
		req.Utype = int32(models.EQKCOUPON_UTYPE_NOVICE_BENEFITS_USER)
	}

	req.Lmode = rr.Lmode
	req.Sum = rr.Sum
	req.Discount = rr.Discount
	return req
}

/*
 *@note  创建推荐有奖的优惠劵
 *@param uid: 用户ID
 *@param recommenderRule: *PSQkCouponRecommendRuleList
 *@param receiverRule: *PSQkCouponRecommendRuleList
 *@return (uint): (错误码)
 */
func createRecommendCid(recommender string, rule *models.PSQkCouponRecommendRuleList, operator models.EQKCOUPON_OPERATOR) uint {
	var timeLayout = "2006.01.02 15:04:05"
	loc, _ := time.LoadLocation("Local")
	curTick := time.Now().Unix()
	var startTick int64
	var endTick int64
	var timeStr string
	var tmpTick time.Time
	var err error

	sql := "INSERT INTO recommend_cid (recommend_id, cid, operator) VALUES "

	for _, rr := range rule.List {
		ccp := recommendCouponRule2CouponBase(rr, operator)

		startTick = curTick
		timeStr = time.Unix(curTick, 0).Format("2006.01.02") + " 00:00:00"
		tmpTick, err = time.ParseInLocation(timeLayout, timeStr, loc)
		if err == nil {
			startTick = tmpTick.Unix()
		}

		endTick = curTick + int64(rr.ExpiryDay*models.DAY_UNIT)
		timeStr = time.Unix(endTick, 0).Format("2006.01.02") + " 23:59:59"
		tmpTick, err = time.ParseInLocation(timeLayout, timeStr, loc)
		if err == nil {
			endTick = tmpTick.Unix()
		}

		cid, errCode := CreateCoupon(ccp, startTick, endTick, 0)
		if errCode != errorcode.EC_GL_SUCCESS {
			log.Debugf("create coupon failed!")
			continue
		}

		sql += fmt.Sprintf("('%s', %d, %d),", recommender, cid, operator)
	}

	sql = sql[:len(sql)-1]

	_, err = qingkeMysqlHelper.Exec(sql)
	if err != nil {
		log.Warn(err.Error())
		return errorcode.EC_GL_EXEC_SQL_FAIL
	}

	return errorcode.EC_GL_SUCCESS
}

/*
 *@note  创建推荐有奖的优惠劵
 *@param uid: 用户ID
 *@param recommenderRule: *PSQkCouponRecommendRuleList
 *@param receiverRule: *PSQkCouponRecommendRuleList
 *@return (uint): (错误码)
 */
func CreateRecommendCoupon(recommender string, recommenderRule *models.PSQkCouponRecommendRuleList, receiverRule *models.PSQkCouponRecommendRuleList) uint {
	errCode := createRecommendCid(recommender, recommenderRule, models.EQKCOUPON_OPERATOR_RECOMMENDER)
	if errCode != errorcode.EC_GL_SUCCESS {
		return errCode
	}

	errCode = createRecommendCid(recommender, receiverRule, models.EQKCOUPON_OPERATOR_RECEIVER)
	if errCode != errorcode.EC_GL_SUCCESS {
		return errCode
	}

	sql := "INSERT INTO recommend_info(recommend_id)VALUES(?)"
	_, err := qingkeMysqlHelper.Insert(sql, recommender)
	if err != nil {
		log.Warn(err.Error())
		return errorcode.EC_QKCOUPON_CREATE_RECOMMEND_FAIL
	}

	return errorcode.EC_GL_SUCCESS
}
